<?php

namespace App\Http\Controllers\Strator;

// use App\Exports\OnTheJobExport;
use App\Http\Controllers\Controller;
use Illuminate\Database\Eloquent\Model;
use App\Models\Strator\StratorInventory;
use App\Models\Strator\StratorProduct;
use App\Models\Strator\StratorInventoryDetail;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\DB;
use App\Models\Strator\StratorSupplier;
use App\Models\Strator\StratorCustomer;
// use Maatwebsite\Excel\Facades\Excel;
use Carbon\Carbon;

class StratorInventoryController extends Controller
{
    protected Request $request;
    protected Model $model;

    public function __construct(Request $request,StratorInventory $strator)
    {
        $this->request=$request;
        $this->model = $strator;
    }

    /**
     * Display a listing of the resource.
     */
    public function index()
    {
        $perPage=$this->request->per_page??10;
        if($this->request->filled('start')&&$this->request->filled('end')){
            if ($this->request->type==1) {
                $list=$this->model
                ->modelSearch($this->request,$this->model)
                ->whereBetween('in_time',[$this->request->start,$this->request->end])
                // ->with(['detail'])
                // ->orderByDesc('id')
                ->orderBy('status', 'asc')
                ->orderBy('id', 'desc')
                ->paginate($perPage);
            } else {
                $list=$this->model
                ->modelSearch($this->request,$this->model)
                ->whereBetween('out_time',[$this->request->start,$this->request->end])
                // ->with(['detail'])
                // ->orderByDesc('id')
                ->orderBy('status', 'asc')
                ->orderBy('id', 'desc')
                ->paginate($perPage);
            }
        } else {
            $list=$this->model
            ->modelSearch($this->request,$this->model)
            // ->with(['detail'])
            // ->orderByDesc('id')
            ->orderBy('status', 'asc')
            ->orderBy('id', 'desc')
            ->paginate($perPage);
        }
        if($this->request->type==1){
            $this->saveOperationLog('查询入库单列表');
        }else{
            $this->saveOperationLog('查询出库单列表');
        }
        return $this->success($list);
    }
    public function exportinventory()
    {
        $list = [];
        $datamodel = StratorInventoryDetail::query()->where('type', $this->request->type);
        if($this->request->filled('start')&&$this->request->filled('end')){
            $datamodel=$datamodel->whereBetween('in_time',[$this->request->start,$this->request->end]);
        }
        if($this->request->filled('out_type')){
            $datamodel=$datamodel->where('out_type',$this->request->out_type);
        }
        if($this->request->filled('in_type')){
            $datamodel=$datamodel->where('in_type',$this->request->in_type);
        }
        if($this->request->filled('batch_no')){
            $datamodel=$datamodel->where('batch_no',$this->request->batch_no);
        }
        if($this->request->filled('supplier_name')){
            $datamodel=$datamodel->where('supplier_name','like','%'.$this->request->supplier_name.'%');
        }
        if($this->request->filled('customer_name')){
            $datamodel=$datamodel->where('customer_name','like','%'.$this->request->customer_name.'%');
        }
        if($this->request->filled('department_name')){
            $datamodel=$datamodel->where('department_name','like','%'.$this->request->department_name.'%');
        }
        $data = $datamodel->get();
        foreach ($data as $k=>$v){
            $list[$k]['order_sn'] = $v->order_sn;
            $list[$k]['batch_no'] = $v->batch_no;
            if($this->request->type == 1){
                $list[$k]['in_time'] = $v->in_time;
                $list[$k]['in_type'] = $this->getType1($v->in_type);
            }else{
                $list[$k]['out_time'] = $v->out_time;
                $list[$k]['out_type'] = $this->getType2($v->in_type);
            }
            $list[$k]['status'] = $v->status==2?'已完成':'草稿';
            $list[$k]['product_name'] = $v->product_name.'-'.$v->product_attr;
            $list[$k]['quantity'] = $v->quantity;
            if($this->request->type == 1){
                $list[$k]['supplier_name'] = $v->supplier_name;
            }else{
                $list[$k]['customer_name'] = $v->customer_name;
                $list[$k]['department_name'] = $v->department_name;
            }
            $list[$k]['remark'] = $v->remark;
            $list[$k]['operator'] = $v->operator;
            $list[$k]['updated_at'] = Carbon::parse($v->updated_at?$v->updated_at:$v->created_at)->format('Y-m-d H:i:s');;
        }
        // $count = $data->count();
        if($this->request->type==1){
            $filename = '入库单导出列表.xlsx';
            // $header = ['入库单号','批次号','入库时间','入库类型','入库状态','入库产品','入库数量','供应商名称','入库备注','最后操作人','最后操作时间'];
            $header = '{"order_sn":"入库单号","batch_no":"批次号","in_time":"入库时间","in_type":"入库类型","status":"入库状态","product_name":"入库产品","quantity":"入库数量","supplier_name":"供应商名称","remark":"入库备注","operator":"最后操作人","updated_at":"最后操作时间"}';
            $this->saveOperationLog('导出入库单');
            // return Excel::download(new OnTheJobExport($list,$header,$count),$filename);
            return $this->success(compact('list','header', 'filename'));
        }else{
            $filename = '出库单导出列表.xlsx';
            // $header = ['出库单号','批次号','出库时间','出库类型','出库状态','出库产品','出库数量','客户名称','部门名称','出库备注','最后操作人','最后操作时间'];
            $header = '{"order_sn":"出库单号","batch_no":"批次号","out_time":"出库时间","out_type":"出库类型","status":"出库状态","product_name":"出库产品","quantity":"出库数量","customer_name":"客户名称","department_name":"部门名称","remark":"出库备注","operator":"最后操作人","updated_at":"最后操作时间"}';
            $this->saveOperationLog('导出出库单');
            // return Excel::download(new OnTheJobExport($list,$header,$count),$filename);
            return $this->success(compact('list','header', 'filename'));
        }
    }
    protected function getType1($type){
        switch ($type){
            case 1:
                $data = '产品采购入库';
                break;
            case 2:
                $data = '材料采购入库';
                break;
            default:
                $data = '';

        }
        return $data;
    }
    protected function getType2($type){
        switch ($type){
            case 1:
                $data = '生产出库';
                break;
            case 2:
                $data = '销售出库';
                break;
            default:
                $data = '';

        }
        return $data;
    }
    public function getItemById()
    {
        $list=StratorInventoryDetail::query()
        ->where('type', 1)
        ->whereIn('product_id', $this->request->ids)->get();
        return $this->success($list);
    }
    public function getItem()
    {
        if($this->request->filled('supplier_name')){
            $list=StratorInventoryDetail::query()
            ->where('supplier_name', $this->request->supplier_name)
            ->where('type', 1);
            if($this->request->filled('start')&&$this->request->filled('end')){
                $list=$list->whereBetween('in_time',[$this->request->start,$this->request->end]);
            }
            if($this->request->filled('batch_no')){
                $list=$list->where('batch_no','like','%'.$this->request->batch_no.'%');
            }
            if($this->request->filled('product_attr')){
                $list=$list->where('product_attr','like','%'.$this->request->product_attr.'%');
            }
            if($this->request->filled('productIds')){
                $list=$list->whereIn('product_id', $this->request->productIds)
                ->orderByDesc('id');
            }elseif($this->request->filled('productId')){
                $list=$list->where('product_id', $this->request->productId)
                ->orderByDesc('id');
            }elseif($this->request->filled('product_id')){
                $list=$list->where('product_id', $this->request->product_id)
                ->orderByDesc('id');
            }elseif($this->request->filled('productName')){
                $list=$list->where('product_name', $this->request->productName)
                ->orderByDesc('id');
            }elseif($this->request->filled('expProductName')){
                $list=$list->where('product_name', '!=' ,$this->request->expProductName)
                ->orderByDesc('id');
            }else{
                $list=$list->orderByDesc('id');
            }
        }elseif($this->request->filled('customer_name')){
            $list=StratorInventoryDetail::query()
            ->where('customer_name', $this->request->customer_name)
            ->where('type', 2);
            if($this->request->filled('start')&&$this->request->filled('end')){
                $list=$list->whereBetween('out_time',[$this->request->start,$this->request->end]);
            }
            if($this->request->filled('batch_no')){
                $list=$list->where('batch_no','like','%'.$this->request->batch_no.'%');
            }
            if($this->request->filled('product_attr')){
                $list=$list->where('product_attr','like','%'.$this->request->product_attr.'%');
            }
            if($this->request->filled('productIds')){
                $list=$list->whereIn('product_id', $this->request->productIds)
                ->orderByDesc('id');
            }elseif($this->request->filled('productId')){
                $list=$list->where('product_id', $this->request->productId)
                ->orderByDesc('id');
            }elseif($this->request->filled('product_id')){
                $list=$list->where('product_id', $this->request->product_id)
                ->orderByDesc('id');
            }elseif($this->request->filled('productName')){
                $list=$list->where('product_name', $this->request->productName)
                ->orderByDesc('id');
            }elseif($this->request->filled('expProductName')){
                $list=$list->where('product_name', '!=' ,$this->request->expProductName)
                ->orderByDesc('id');
            }else{
                $list=$list->orderByDesc('id');
            }
        }elseif($this->request->filled('department_name')){
            $list=StratorInventoryDetail::query()
            ->where('department_name', $this->request->department_name)
            ->where('type', 2);
            if($this->request->filled('start')&&$this->request->filled('end')){
                $list=$list->whereBetween('out_time',[$this->request->start,$this->request->end]);
            }
            if($this->request->filled('batch_no')){
                $list=$list->where('batch_no','like','%'.$this->request->batch_no.'%');
            }
            if($this->request->filled('product_attr')){
                $list=$list->where('product_attr','like','%'.$this->request->product_attr.'%');
            }
            if($this->request->filled('productIds')){
                $list=$list->whereIn('product_id', $this->request->productIds)
                ->orderByDesc('id');
            }elseif($this->request->filled('productId')){
                $list=$list->where('product_id', $this->request->productId)
                ->orderByDesc('id');
            }elseif($this->request->filled('product_id')){
                $list=$list->where('product_id', $this->request->product_id)
                ->orderByDesc('id');
            }elseif($this->request->filled('productName')){
                $list=$list->where('product_name', $this->request->productName)
                ->orderByDesc('id');
            }elseif($this->request->filled('expProductName')){
                $list=$list->where('product_name', '!=' ,$this->request->expProductName)
                ->orderByDesc('id');
            }else{
                $list=$list->orderByDesc('id');
            }
        }elseif($this->request->filled('check_ft')){
            $list=StratorInventoryDetail::query()
            ->where('type', 1);
            if($this->request->filled('start')&&$this->request->filled('end')){
                $list=$list->whereBetween('in_time',[$this->request->start,$this->request->end]);
            }
            if($this->request->filled('batch_no')){
                $list=$list->where('batch_no','like','%'.$this->request->batch_no.'%');
            }
            if($this->request->filled('product_attr')){
                $list=$list->where('product_attr','like','%'.$this->request->product_attr.'%');
            }
            if($this->request->filled('productIds')){
                $list=$list->whereIn('product_id', $this->request->productIds)
                ->orderByDesc('id');
            }elseif($this->request->filled('productId')){
                $list=$list->where('product_id', $this->request->productId)
                ->orderByDesc('id');
            }elseif($this->request->filled('product_id')){
                $list=$list->where('product_id', $this->request->product_id)
                ->orderByDesc('id');
            }elseif($this->request->filled('productName')){
                $list=$list->where('product_name', $this->request->productName)
                ->orderByDesc('id');
            }elseif($this->request->filled('expProductName')){
                $list=$list->where('product_name', '!=' ,$this->request->expProductName)
                ->orderByDesc('id');
            }else{
                $list=$list->orderByDesc('id');
            }
        }else{
            $list=StratorInventoryDetail::query()
            ->where('product_id', $this->request->product_id)
            ->where('type', $this->request->type);
            if($this->request->filled('batch_no')){
                $list=$list->where('batch_no','like','%'.$this->request->batch_no.'%');
            }
            if($this->request->filled('product_attr')){
                $list=$list->where('product_attr','like','%'.$this->request->product_attr.'%');
            }
            if($this->request->filled('start')&&$this->request->filled('end')){
                if($this->request->type==1){
                    $list=$list->whereBetween('in_time',[$this->request->start,$this->request->end]);
                }else{
                    $list=$list->whereBetween('out_time',[$this->request->start,$this->request->end]);
                }
            }
            if($this->request->filled('productIds')){
                $list=$list->whereIn('product_id', $this->request->productIds)
                ->orderByDesc('id');
            }elseif($this->request->filled('productId')){
                $list=$list->where('product_id', $this->request->productId)
                ->orderByDesc('id');
            }elseif($this->request->filled('productName')){
                $list=$list->where('product_name', $this->request->productName)
                ->orderByDesc('id');
            }elseif($this->request->filled('expProductName')){
                $list=$list->where('product_name', '!=' ,$this->request->expProductName)
                ->orderByDesc('id');
            }else{
                $list=$list->orderByDesc('id');
            }
        }
        if($this->request->type==1){
            $this->saveOperationLog('查询产品入库单');
        }else{
            $this->saveOperationLog('查询产品出库单');
        }
        if($this->request->filled('page')&&!$this->request->filled('productIds')&&!$this->request->filled('productId')&&!$this->request->filled('productName')&&!$this->request->filled('expProductName')){
            $perPage=$this->request->per_page??10;
            return $this->success($list->paginate($perPage));
        }else{
            return $this->success($list->get());
        }
    }

    /**
     * Show the form for creating a new resource.干什么？
     */
    public function create()
    {
        //
    }

    /**
     * Store a newly created resource in storage.
     */
    public function store()
    {
        $data=$this->request->only($this->storeOnly());
        $data['order_sn'] = $this->getSn($this->request->type);
        if ($this->request->status==2) {
            $this->buildDetail($this->request,$data['order_sn']);
        }
        // 如果供应商或者客户是数据库里没有的，那么就新增
        if($this->request->filled('supplier_name')){
            $supplier = StratorSupplier::query()->where('name', $this->request->supplier_name)->count();
            if(empty($supplier)||$supplier==0) {
                $adddata = [];
                $adddata[0] = [
                    'created_at'=>now(),
                    'name'=>$this->request->supplier_name,
                ];
                DB::table('strator_suppliers')->insert($adddata);
            }
        }
        if($this->request->filled('customer_name')){
            $customer = StratorCustomer::query()->where('name', $this->request->customer_name)->count();
            if(empty($customer)||$customer==0) {
                $adddata = [];
                $adddata[0] = [
                    'created_at'=>now(),
                    'name'=>$this->request->customer_name,
                ];
                DB::table('strator_customers')->insert($adddata);
            }
        }
        $this->model->fill($data);
        $this->model->save();
        if($this->request->type==1){
            $this->saveOperationLog('新增入库单');
        }else{
            $this->saveOperationLog('新增出库单');
        }
        return $this->success(['id'=>$this->model->id]);
    }
    protected function buildDetail($request,$order_sn){
        // 按数据生成出入库明细
        $contents = json_decode($request->contents);
        $data = [];
        $add_now = now();
        for ($i=0;$i<count($contents);$i++){
            if ($request->type==1) {
                $this->updateProductQuantityAdd($contents[$i]->productId, $contents[$i]->quantity);
            } else {
                $this->updateProductQuantityDel($contents[$i]->productId, $contents[$i]->quantity);
            }
            // 如果传了批次ID，那么需要更新当前批次的已使用数量
            if(!empty($contents[$i]->batch_id)){
                $this->updateInventoryQuantityDel($contents[$i]->batch_id, $contents[$i]->quantity);
            }
            $batch_no = '';
            if(!empty($request->batch_no)){
                $batch_no = $request->batch_no;
            }
            if(!empty($contents[$i]->batchNo)){
                $batch_no = $contents[$i]->batchNo;
            }
            $data[$i]= [
                'order_sn'=> $order_sn,
                'created_at'=>$add_now,
                'batch_id'=>$contents[$i]->batch_id??'',
                'batch_no'=>$batch_no,
                'remark'=>$request->remark??'',
                'share_contents'=>$request->share_contents??null,
                'purchase_no'=>$request->purchase_no??'',
                'in_time'=>$request->in_time??null,
                'out_time'=>$request->out_time??null,
                'type'=>$request->type??1,
                'in_type'=>$request->in_type??1,
                'out_type'=>$request->out_type??1,
                'out_type'=>$request->out_type??1,
                'status'=>2,
                'supplier_name'=>$request->supplier_name??'',
                'customer_name'=>$request->customer_name??'',
                'department_id'=>$request->department_id??null,
                'department_name'=>$request->department_name??'',
                'operator'=>$request->operator??'',
                'operator_id'=>$request->operator_id??null,
                'product_name'=>$contents[$i]->productName,
                'product_id'=>$contents[$i]->productId,
                'quantity'=>$contents[$i]->quantity,
                'product_type'=>$contents[$i]->product_type??'',
                'product_attr'=>$contents[$i]->product_attr??'',
            ];
        }

        if(count($data)>0){
            DB::table('strator_inventory_details')->insert($data);
        }
    }
    // 产品库存增加
    protected function updateProductQuantityAdd($product_id,$quantity){
        // 找到对应产品
        $product = StratorProduct::query()->where('id',$product_id)->first();
        $product->is_instore = 1; // 更新为已操作过入库
        $product->inventory = $product->inventory+$quantity;
        $product->save();
    }
    // 产品库存减少
    protected function updateProductQuantityDel($product_id,$quantity){
        // 找到对应产品
        $product = StratorProduct::query()->where('id',$product_id)->first();
        $product->is_instore = 1; // 更新为已操作过入库
        $product->inventory = $product->inventory-$quantity;
        $product->save();
    }
    // 批次库存减少
    protected function updateInventoryQuantityDel($batch_id,$quantity){
        // 找到对应产品
        $inventoryItem = StratorInventoryDetail::query()->where('id',$batch_id)->first();
        $inventoryItem->isused = $inventoryItem->isused+$quantity;
        $inventoryItem->save();
    }
    //设置订单号
    private function getSn($type){
        $car = StratorInventory::query()
            ->select('id')
            ->where('id','>',0)
            ->orderByDesc('id')
            ->first();
        if($car){
            $num = $car->id+1;
        }else{
            $num = 1;
        }
        if ($num<10) {
            $num = '000'.$num;
        } elseif ($num<100) {
            $num = '00'.$num;
        } elseif ($num<1000) {
            $num = '0'.$num;
        }
        if ($type==1) {
            return 'rkd'.date('Ymd',time()).$num;
        } elseif ($type==2) {
            return 'ckd'.date('Ymd',time()).$num;
        }
    }
    //
    public function storeOnly():array{
        return [
            'sort',
            'remark',
            'status',
            'in_time',
            'out_time',
            'type',
            'in_type',
            'out_type',
            'order_sn',
            'supplier_name',
            'customer_name',
            'contents',
            'share_contents',
            'purchase_no',
            'operator',
            'operator_id',
            'batch_no',
            'department_id',
            'department_name',
            'is_sale',
        ];
    }

    /**
     * Display the specified resource.
     */
    public function show()
    {
//        return $this->success($this->request->user());
        $model=$this->model->findOrFail($this->request->id);
        return $this->success($model);
    }

    /**
     * Update the specified resource in storage.
     */
    public function update()
    {
        $model=$this->model->findOrFail($this->request->id);
        // 如果确定入库的时候，后台已出库，则不能重复出入库
        if($model->status == 2 && $this->request->status==2){
            return $this->fail('当前出入库单已操作过出入库，请刷新页面后重试');
        }
        // 如果编辑草稿时，后台已出库，则不能编辑
        if($model->status == 2 && $this->request->status==1){
            return $this->fail('当前出入库单已操作过出入库，请刷新页面后重试');
        }
        if ($this->request->filled('contents') && $this->request->status==2) {
            // 采购单入库
            if($this->request->isFt==1){
                $this->buildDetailFt($this->request,$model->order_sn);
            }else{
                $this->buildDetail($this->request,$model->order_sn);
            }
        }
        // return $this->successMsg();
        $origin=$model->toArray();
        $data=$this->request->except($this->updateExcept());
        $model->fill($data);
        $model->save();
        if($this->request->type==1){
            $this->saveOperationLog('修改入库单',$origin);
        }else{
            $this->saveOperationLog('修改出库单',$origin);
        }
        return $this->successMsg();
    }
    protected function buildDetailFt($request,$order_sn){
        // 按数据生成出入库明细
        $contents = json_decode($request->contents);
        $share_contents = json_decode($request->share_contents);
        $data = [];
        $add_now = now();
        for ($i=0;$i<count($contents);$i++){
            $fen_num_list = []; // 分摊数量计算，处理精度问题
            $add_total = 0;
            $share_len = count($share_contents)-1;
            for ($j=0;$j<$share_len;$j++){
                $item_quantity = round($contents[$i]->quantity*$share_contents[$j]->rate, 0);
                $fen_num_list[]=$item_quantity;
                $add_total = round($add_total+$item_quantity, 0);
            }
            $fen_num_list[$share_len]=round($contents[$i]->quantity-$add_total,0);
            for ($j=0;$j<count($share_contents);$j++){
                // 根据分摊人按人插入入库明细
                $data[]= [
                    'order_sn'=> $order_sn,
                    'created_at'=>$add_now,
                    'batch_id'=>$contents[$i]->batch_id??'',
                    'batch_no'=>$request->batch_no.'-'.$share_contents[$j]->code,
                    'remark'=>$request->remark??'',
                    'share_contents'=>$request->share_contents??null,
                    'purchase_no'=>$request->purchase_no??'',
                    'in_time'=>$request->in_time??null,
                    'out_time'=>$request->out_time??null,
                    'type'=>$request->type??1,
                    'in_type'=>$request->in_type??1,
                    'out_type'=>$request->out_type??1,
                    'out_type'=>$request->out_type??1,
                    'status'=>2,
                    'supplier_name'=>$request->supplier_name??'',
                    'customer_name'=>$request->customer_name??'',
                    'department_id'=>$request->department_id??null,
                    'department_name'=>$request->department_name??'',
                    'operator'=>$request->operator??'',
                    'operator_id'=>$request->operator_id??null,
                    'product_name'=>$contents[$i]->productName,
                    'product_id'=>$contents[$i]->productId,
                    'quantity'=>$fen_num_list[$j],
                    'product_type'=>$contents[$i]->product_type??'',
                    'product_attr'=>$contents[$i]->product_attr??'',
                ];
            }
            if ($request->type==1) {
                // 拿到分摊后的总数
                $this->updateProductQuantityAdd($contents[$i]->productId, $contents[$i]->quantity);
            } else {
                $this->updateProductQuantityDel($contents[$i]->productId, $contents[$i]->quantity);
            }
        }

        if(count($data)>0){
            info($data);
            DB::table('strator_inventory_details')->insert($data);
        }
    }
    //
    public function updateExcept():array
    {
        return [
            'id',
            'isFt',
        ];
    }
    /**
     * Remove the specified resource from storage.
     */
    public function destroy()
    {
        $model=$this->model->findOrFail($this->request->id);
        $model->delete();
        $this->saveOperationLog('删除草稿');
        return $this->successMsg('删除成功');
    }
}
